//
//  BMAScoreAdvancementChartView.m
//  Autismus
//
//  Created by Nicolas CHENG on 15/01/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "BMAScoreAdvancementChartView.h"

#import "BMAScoreAdvChartViewDataSource.h"
#import "BMAScoreAdvChartViewDelegate.h"

@implementation BMAScoreAdvancementChartView

@synthesize delegate;
@synthesize dataSource;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self != nil) 
    {
        // general
        self.backgroundColor = [UIColor clearColor];
        
        // ajout de la grille du fond
        _gridBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
        [self addSubview:_gridBackgroundView];
    }
    
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self != nil) 
    {
        // general
        self.backgroundColor = [UIColor clearColor];
        
        // ajout de la grille du fond
        _gridBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
        [self addSubview:_gridBackgroundView];
    }
    
    return self;
    
}

//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////     REQUIRED     /////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

// Nombre de jeux pour la date en cours
- (NSUInteger)numberOfGames
{
    return [self.dataSource scoreAdvancementChartViewNumberOfGames:self];
}

// Données pour la partie à un index donné à une date donnée
- (BMAStats *)statsAtIndex:(NSUInteger)index
{
    return [self.dataSource scoreAdvancementChartView:self statsAtIndex:index];
}

//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////     OPTIONAL     /////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

// Couleur de la grille du fond (gris clair par défaut)
- (UIColor *)gridColor
{
    UIColor *result = nil;   
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartViewGridColor:)])
    {
        result = [self.dataSource scoreAdvancementChartViewGridColor:self];
    }
    
    if (result == nil)
    {
        result = [UIColor lightGrayColor];
    }
    
    return result;
}
    
// Couleur de la barre des temps en fonction du type de jeux (couleur par défaut choisie par hasard)
- (UIColor *)colorForVerticalBarOfIDGame:(BMAIDGame)idGame
{
    UIColor *result = nil;
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartView:colorForVerticalBarOfIDGame:)])
    {
        result = [self.dataSource scoreAdvancementChartView:self colorForVerticalBarOfIDGame:idGame];
    }
    
    if (result == nil)
    {
        result = [UIColor randomColor];
    }
    
    return result;
}

// Couleur du tracé de la ligne des scores (couleur grise foncée par défaut)
- (UIColor *)colorOfTheLineScores
{
    UIColor *result = nil;
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartViewColorOfTheLineScores)])
    {
        result = [self.dataSource scoreAdvancementChartViewColorOfTheLineScores:self];
    }
    
    if (result == nil)
    {
        result = [UIColor darkGrayColor];
    }
    
    return result;
}

// Couleur des axes (couleur gris clair par défaut)
- (UIColor *)colorOfAxis
{
    UIColor *result = nil;
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartColorOfAxis:)])
    {
        result = [self.dataSource scoreAdvancementChartColorOfAxis:self];
    }
    
    if (result == nil)
    {
        result = [UIColor lightGrayColor];
    }
    
    return result;
}

// Affichage de la grille du fond (valeur oui par défaut)
- (BOOL)shouldShowGrid
{
    BOOL result = YES;
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartViewShouldShowGrid:)])
    {
        result = [self.dataSource scoreAdvancementChartViewShouldShowGrid:self];
    }
    
    return result;
}

// Nombre d'axe des ordonnées (par défaut = 1), au max il ne pourra en avoir que 2
- (NSUInteger)numberOfYAxis
{
    NSUInteger result = 1;
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartViewNumberOfYAxis:)])
    {
        result = [self.dataSource scoreAdvancementChartViewNumberOfYAxis:self];
    }
    
    if (result == 0)
    {
        result = 1;
    }
    
    if (result > 2)
    {
        result = 2;
    }
    
    return result;
}

// Nom de l'axe des ordonnées à un index donné (chaine vide par défaut)
- (NSString *)yAxisNameAtIndex:(NSUInteger)index
{
    NSString *result = @"";
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartView:yAxisNameAtIndex:)])
    {
        result = [self.dataSource scoreAdvancementChartView:self yAxisNameAtIndex:index];
    }
    
    if (result == nil)
    {
        result = @"";
    }
    
    return result;
}

// Nom de l'axe des abscisses (chaine vide par défaut)
- (NSString *)xAxisName
{
    NSString *result = @"";
    
    if (self.dataSource && [self.dataSource respondsToSelector:@selector(scoreAdvancementChartViewXAxisName:)])
    {
        result = [self.dataSource scoreAdvancementChartViewXAxisName:self];
    }
    
    if (result == nil)
    {
        result = @"";
    }
    
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////     RENDER     /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
    
    CGFloat width = rect.size.width;
    CGFloat height = rect.size.height;
    
    CGFloat margin = AUTIMO_DEFAULT_BAR_WIDTH * 1;          // une marge entre 2 parties au minimum
    
    NSUInteger numberOfGames = [self numberOfGames];
    
    CGFloat unusedSpace = width - (AUTIMO_DEFAULT_BAR_WIDTH + margin) * numberOfGames; 
    
    if (unusedSpace > 0)
    {
        // agrandir la marge entre 2 parties pour remplir tout l'espace
        margin += ceilf(unusedSpace / numberOfGames);
    }
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // GRID
    {
        if ([self shouldShowGrid])
        {
            NSUInteger i = 0;
            NSUInteger part = 0.0f;
            
            CGContextSaveGState(context);
            
            // vertical
            NSUInteger numberOfColumns = 6;
            part = roundf(width/numberOfColumns);
            
            for (i = 0; i < numberOfColumns - 1; i++)
            {
                CGContextSaveGState(context);
                CGContextMoveToPoint(context, (i+1)*part - 0.5, 0);
                CGContextAddLineToPoint(context, (i+1)*part - 0.5, height);
            }
            
            // horizontal
            NSUInteger numberOfRows = 4;
            part = roundf(height/numberOfRows);
            for (i = 0; i < numberOfRows; i++)
            {
                CGContextSaveGState(context);
                CGContextMoveToPoint(context, 0, (i == 0) ? 0 : i * part - 0.5);
                CGContextAddLineToPoint(context, width, (i == 0) ? 0 : i * part - 0.5);
            }
            
            CGContextSetStrokeColorWithColor(context, [self gridColor].CGColor);
            CGContextSetLineWidth(context, 1.0);
            CGContextStrokePath(context);
            CGContextRestoreGState(context);
        }
    }
    
    // X AXIS
    {
        CGContextSaveGState(context);
        CGContextMoveToPoint(context, 0, height);
        CGContextAddLineToPoint(context, width, height);
        CGContextSetStrokeColorWithColor(context, [self colorOfAxis].CGColor);
        CGContextSetLineWidth(context, 1.0);
        CGContextStrokePath(context);
        CGContextRestoreGState(context);
    }
    
    // Y AXIS    
    {
        CGContextSaveGState(context);
        CGContextMoveToPoint(context, 0, 0);
        CGContextAddLineToPoint(context, 0, height);
        CGContextSetStrokeColorWithColor(context, [self colorOfAxis].CGColor);
        CGContextSetLineWidth(context, 1.0);
        CGContextStrokePath(context);
        CGContextRestoreGState(context);
        
        if ([self numberOfYAxis] == 2)
        {
            CGContextSaveGState(context);
            CGContextMoveToPoint(context, width, 0);
            CGContextAddLineToPoint(context, width, height);
            CGContextSetStrokeColorWithColor(context, [self colorOfAxis].CGColor);
            CGContextSetLineWidth(context, 1.0);
            CGContextStrokePath(context);
            CGContextRestoreGState(context);
        }
    }
    
    CGPoint prevPoint = CGPointZero;
    
    for (NSUInteger i = 0; i < numberOfGames; i++)
    {
        BMAStats *stats = [self statsAtIndex:i];
        
        // BAR (temps)
        {
            CGContextSaveGState(context);
            
            DLOG(@"elapsedTime = %f / max = %f", stats.elapsedTime, stats.maxElapsedTime);
            
            CGFloat h = roundf(height * stats.elapsedTime/stats.maxElapsedTime);
            
            CGRect rect = CGRectMake(i * (AUTIMO_DEFAULT_BAR_WIDTH + margin) + margin - margin / 2, height-h, AUTIMO_DEFAULT_BAR_WIDTH, h);
            
            DLOG(@"%f %f %f %f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
            
            CGPathRef path = CGPathCreateWithRect(rect, NULL);
            
            [[self colorForVerticalBarOfIDGame:stats.idGame] set];
            CGContextAddPath(context, path);
            CGContextFillPath(context);
            CGContextRestoreGState(context);
            CGPathRelease(path);
        }
        
        // STROKE DU SCORE
        {
            CGFloat y = height - roundf(height * stats.score/stats.maxScore);
            
            CGPoint curPoint = CGPointMake(i * (AUTIMO_DEFAULT_BAR_WIDTH + margin) + margin - margin / 2 + AUTIMO_DEFAULT_BAR_WIDTH / 2, y);
            
            // circles
            CGContextSaveGState(context);
            [[self colorOfTheLineScores] set];
            CGRect rectangle = CGRectMake(curPoint.x - 4, curPoint.y - 4, 8, 8);
            CGContextFillEllipseInRect(context, rectangle);
            CGContextRestoreGState(context);
            
            // lines
            if (i > 0)
            {
                CGContextSaveGState(context);
                CGContextMoveToPoint(context, prevPoint.x, prevPoint.y);
                CGContextAddLineToPoint(context, curPoint.x, curPoint.y);              
                CGContextSetStrokeColorWithColor(context, [self colorOfTheLineScores].CGColor);
                CGContextSetLineWidth(context, 2.5);
                CGContextStrokePath(context);
                CGContextRestoreGState(context);
            }    
                
            prevPoint = curPoint;

        }
    }
}

@end
